home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 1.iso / desktop / winmaze4.zip / ORACLE.CPP < prev    next >
C/C++ Source or Header  |  1994-04-28  |  3KB  |  100 lines

  1. #include "oracle.h"
  2.  
  3. #ifndef TRUE
  4. #define TRUE -1
  5. #endif
  6. #ifndef FALSE
  7. #define FALSE 0
  8. #endif
  9.  
  10. oracle::oracle(char *seed,int max_r_n_plus_1)
  11. //      An eight (or fewer) character seed and the upper bound on the
  12. // numbers to be returned specify the random number generator. 
  13.   {
  14.     modulus=max_r_n_plus_1;
  15.     prime=equal_or_larger_prime(modulus);
  16.     // A prime modulus is needed to insure that the number returned from
  17.     // the random number generator are uniformly distributed.
  18.     for (int r_n_index_1=0; ((r_n_index_1 < 8) && (seed[r_n_index_1]));
  19.      r_n_index_1++)        // insert seed
  20.       {
  21.         if (seed[r_n_index_1] < '\0')
  22.           seed[r_n_index_1]=-seed[r_n_index_1];
  23.         r_n[r_n_index_1]=long(seed[r_n_index_1])%prime;
  24.       }
  25.     int r_n_index_2=7;
  26.     while (r_n_index_1 > 0) // right justify
  27.       {
  28.          r_n_index_1--;
  29.          r_n[r_n_index_2]=r_n[r_n_index_1];
  30.          r_n_index_2--;
  31.       }
  32.     while (r_n_index_2 >= 0) // fill with leading 1's
  33.       {
  34.         r_n[r_n_index_2]=1;
  35.         r_n_index_2--;
  36.       }
  37.   }
  38.  
  39. long oracle::equal_or_larger_prime(int starting_value)
  40. //      Try consecutive values until a prime number is found.
  41.   {
  42.     long result=long(starting_value);
  43.     while (! is_prime(result)) result++;
  44.     return result;
  45.   }
  46.  
  47. int oracle::is_prime(long possible_prime)
  48. //      If no number up to the square root of a number evenly divides the
  49. // number, then the number is prime.
  50.   {
  51.     long new_max_divisor;
  52.     int  result=TRUE;
  53.     long max_divisor=possible_prime;
  54.     int  square_root=FALSE;
  55.  
  56.     while (! square_root)
  57.       {
  58.         if ((new_max_divisor=(max_divisor+possible_prime/max_divisor)/2l)
  59.          < max_divisor)
  60.           max_divisor=new_max_divisor;
  61.         else
  62.           square_root=TRUE;
  63.       }  // max_divisor=sqrt(possible_prime) via Newton's method.
  64.     for (long divisor=2l; ((result) && (divisor <= max_divisor)); divisor++)
  65.       result=((divisor*(possible_prime/divisor)) != possible_prime);
  66.     return result;
  67.   }
  68.  
  69. int oracle::random_number()
  70. //     Ignoring initialization, r_n[i] is the sum of the 8 previous values of
  71. // r_n[i] mod prime. r_n[7] is computed until it's within the desired range and
  72. // then it's returned.
  73. //     It is assumed that a "long" can contain the sum of any two "int"s.
  74.   {
  75.     int  r_n_index_1;
  76.     int  r_n_index_2;
  77.     long result;
  78.     long tem_long;
  79.  
  80.     do
  81.       {
  82.         result=r_n[0];
  83.         r_n_index_1=0;
  84.         r_n_index_2=1;
  85.         while (r_n_index_2 < 8)
  86.           {
  87.             tem_long=r_n[r_n_index_2];
  88.             r_n[r_n_index_1]=tem_long;
  89.             result+=tem_long;
  90.             if (result >= prime)
  91.               result-=prime;
  92.             r_n_index_1=r_n_index_2;
  93.             r_n_index_2++;
  94.           }
  95.         r_n[7]=result;
  96.       }
  97.     while (result >= long(modulus));
  98.     return int(result);
  99.   }
  100.